<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>rabbit web 3d run</title>
    <style>
        body {
            margin: 0;
            overflow: hidden; /* 溢出隐藏 */
        }
    </style>
    <script src="./libs/three-r93.js"></script>
    <script src="./libs/Detector.js"></script>
    <script src="./libs/dat.gui.min.js"></script>
    <script src="./libs/stats.min.js"></script>
    <script src="./libs/OrbitControls.js"></script>
    <script src="./libs/GLTFLoader.js"></script>
    <style>
        #loading {
            position: fixed;
            top: 50%;
            left: 50%;
            color: #FFFFFF;
            font-size: 20px;
            margin-top: -30px;
            margin-left: -40px;
        }
    </style>
</head>
<body>
<p id="loading">loading......</p>
<script>

    let scene, camera, renderer, controls, guiControls, clock, mixer, mixer_left, mixer_right, mixer_back;
    let cube;
    let stats = initStats();
    let texture, textureLoader, plane;
    let play_left, play_center, play_right, play_back;

    /* 场景 */
    function initScene() {

        scene = new THREE.Scene();
        clock = new THREE.Clock();

        play_left = true;
        play_center = true;
        play_right = true;
        play_back = true;
    }

    /* 相机 */
    function initCamera() {

        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
        camera.position.set(0, 0, 20);
        camera.lookAt(new THREE.Vector3(0, 0, 0));

    }

    /* 渲染器 */
    function initRender() {

        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x0E3866);
        document.body.appendChild(renderer.domElement);

    }

    /* 灯光 */
    function initLight() {

        scene.add(new THREE.AmbientLight(0xffffff));

        const pointLight = new THREE.PointLight( 0xffffff, 1, 1000 );
        pointLight.position.set( 500, 500, 500 );
        scene.add( pointLight );
    }

    /* 控制器 */
    function initControls() {

        controls = new THREE.OrbitControls(camera, renderer.domElement);

        /* 属性参数默认 */

    }

    /* 调试插件 */
    function initGui() {

        guiControls = new function () {

             this.left = function () {

                play_left = !play_left;
             };

             this.center = function () {

                play_center = !play_center;
             };

             this.right = function () {

                play_right = !play_right;
             };

             this.back = function () {

                play_back = !play_back;
             };
        };

        let gui = new dat.GUI({width: 150});

        gui.add(guiControls, 'left');
        gui.add(guiControls, 'center');
        gui.add(guiControls, 'right');
        gui.add(guiControls, 'back');

        return;
    }

        function loadTexture(path) {
          var texture = new THREE.Texture();
          var material = new THREE.MeshBasicMaterial({
            map: texture,
            overdraw: true,
            side: THREE.DoubleSide,
          });

          var image = new Image();
          image.onload = function () {
            texture.needsUpdate = true;
            material.map.image = this;

            render();
          };
          image.src = path;

          return material;
        }

    /* 场景中的内容 */
    function initContent() {

        textureLoader = new THREE.TextureLoader();
        texture = textureLoader.load("./models/rabbit-pbr_out/rabbit-texture.png");
        texture.encoding = THREE.sRGBEncoding;
        texture.flipY = false;

        // 加载 glTF 格式的模型
        let loader = new THREE.GLTFLoader();/*实例化加载器*/
/*
        loader.load('models/monkey_textured.glb', function(obj) {

            console.log(obj);

            obj.scene.position.x = 5;
            obj.scene.position.y = 5;
            obj.scene.position.z = 0;

            obj.scene.traverse(function (child) {
                if (child.isMesh) {
                    let m = child;
                    m.receiveShadow = true;
                    m.castShadow = true;
                }
                if (child.isLight) {
                    let l = child;
                    l.castShadow = true;
                    l.shadow.bias = -.003;
                    l.shadow.mapSize.width = 2048;
                    l.shadow.mapSize.height = 2048;
                }
            });

            scene.add(obj.scene);
        });
*/
        //loader.load('./models/rabbit-pbr_out/rabbit-pbr.gltf',function (obj) {
        loader.load('./models/rabbit-pbr_out/rabbit-pbr.gltf',function (obj) {

            console.log(obj);

            obj.scene.position.x = 0;
            obj.scene.position.y = 0;
            obj.scene.position.z = 0;
            
            //obj.scene.material.map = texture;

            document.getElementById('loading').style.display = 'none';

            obj.scene.traverse( function ( child ) {
                
                    if ( child.isMesh ) {

                    child.material = new THREE.MeshStandardMaterial({
                        map: texture,
                        color: 0xffffff,
                        skinning: true,
                        morphTargets: true,
                        morphNormals: true,
                    });

                    console.log(child.material);
                    }
            } );

            mixer = new THREE.AnimationMixer( obj.scene );
        
            obj.animations.forEach( ( clip ) => {
                mixer.clipAction( clip ).play();              
            } );
            
            scene.add(obj.scene);

        },function (xhr) {

            console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

        },function (error) {

            console.log('load error!'+error.getWebGLErrorMessage());

        })

        loader.load('./models/rabbit-pbr_out/rabbit-pbr.gltf',function (obj) {

            console.log(obj);

            obj.scene.position.x = 2;
            obj.scene.position.y = 0;
            obj.scene.position.z = 2;

            obj.scene.rotation.y = -Math.PI/2;
            
            document.getElementById('loading').style.display = 'none';

            obj.scene.traverse( function ( child ) {
                
                    if ( child.isMesh ) {

                    child.material = new THREE.MeshStandardMaterial({
                        map: texture,
                        color: 0xff00ff,
                        skinning: true,
                        morphTargets: true,
                        morphNormals: true,
                    });

                    console.log(child.material);
                    }
            } );

            mixer_right = new THREE.AnimationMixer( obj.scene );
        
            obj.animations.forEach( ( clip ) => {
                mixer_right.clipAction( clip ).play();              
            } );
            
            scene.add(obj.scene);

        },function (xhr) {

            console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

        },function (error) {

            console.log('load error!'+error.getWebGLErrorMessage());

        })

        loader.load('./models/rabbit-pbr_out/rabbit-pbr.gltf',function (obj) {

            console.log(obj);

            obj.scene.position.x = -2;
            obj.scene.position.y = 0;
            obj.scene.position.z = 2;
            
            obj.scene.rotation.y = Math.PI/2;

            document.getElementById('loading').style.display = 'none';

            obj.scene.traverse( function ( child ) {
                
                    if ( child.isMesh ) {

                    child.material = new THREE.MeshStandardMaterial({
                        map: texture,
                        color: 0xffff00,
                        skinning: true,
                        morphTargets: true,
                        morphNormals: true,
                    });

                    console.log(child.material);
                    }
            } );

            mixer_left = new THREE.AnimationMixer( obj.scene );
        
            obj.animations.forEach( ( clip ) => {
                mixer_left.clipAction( clip ).play();              
            } );
            
            scene.add(obj.scene);

        },function (xhr) {

            console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

        },function (error) {

            console.log('load error!'+error.getWebGLErrorMessage());

        })

        loader.load('./models/rabbit-pbr_out/rabbit-pbr.gltf',function (obj) {

            console.log(obj);

            obj.scene.position.x = 0;
            obj.scene.position.y = 0;
            obj.scene.position.z = 4;
            
            obj.scene.rotation.y = Math.PI;

            document.getElementById('loading').style.display = 'none';

            obj.scene.traverse( function ( child ) {
                
                    if ( child.isMesh ) {

                    child.material = new THREE.MeshStandardMaterial({
                        map: texture,
                        color: 0x00ffff,
                        skinning: true,
                        morphTargets: true,
                        morphNormals: true,
                    });

                    console.log(child.material);
                    }
            } );

            mixer_back = new THREE.AnimationMixer( obj.scene );
        
            obj.animations.forEach( ( clip ) => {
                mixer_back.clipAction( clip ).play();              
            } );
            
            scene.add(obj.scene);

        },function (xhr) {

            console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

        },function (error) {

            console.log('load error!'+error.getWebGLErrorMessage());

        })
/*
        // import { BoxBufferGeometry } from 'three';
        // create a geometry
        const geometry = new THREE.BoxBufferGeometry(2, 2, 2);
        // create a default (white) Basic material
        const material = new THREE.MeshBasicMaterial();
        // create a Mesh containing the geometry and material
        cube = new THREE.Mesh(geometry, material);
        cube.position.y = -2;
        cube.position.x = -3;
        // add the mesh to the scene
        scene.add(cube);
*/
/*
        var planematerial = new THREE.MeshLambertMaterial({ map : texture });
        plane = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), planematerial);
        plane.doubleSided = true;
        plane.position.x = 0;
        plane.position.z = -20;
        plane.rotation.z = 0;  // Not sure what this number represents.
        scene.add(plane);
*/
        scene.background = new THREE.CubeTextureLoader()
            .setPath( 'images/' )
            .load( [
                'px.jpg',
                'nx.jpg',
                'py.jpg',
                'ny.jpg',
                'pz.jpg',
                'nz.jpg'
            ] );

        // var materials = [
        //   loadTexture("images/px.jpg"), // right
        //   loadTexture("images/nx.jpg"), // left
        //   loadTexture("images/py.jpg"), // top
        //   loadTexture("images/ny.jpg"), // bottom
        //   loadTexture("images/pz.jpg"), // back
        //   loadTexture("images/nz.jpg"), // front
        // ];

        // var cubmesh = new THREE.Mesh(
        //   new THREE.CubeGeometry(8, 8, 8, 1, 1, 1, materials),
        //   new THREE.MeshFaceMaterial({ side: THREE.DoubleSide })
        // );
        // cubmesh.scale.x = -1;
        // cubmesh.position.x = 3;
        // scene.add(cubmesh); //纹理贴图网格模型添加到场景中
    }

    /* 性能插件 */
    function initStats() {

        let stats = new Stats();

        document.body.appendChild(stats.domElement);

        return stats;

    }

    /* 窗口变动触发 */
    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);

    }

    /* 数据更新 */
    function update() {

        stats.update();

    }

    /* 初始化 */
    function init() {

        initScene();
        initCamera();
        initRender();
        initLight();
        initControls();
        initContent();
        initGui();

        /* 监听事件 */
        window.addEventListener('resize', onWindowResize, false);

    }

    /* 循环渲染 */
    function animate() {

        requestAnimationFrame(animate);
        
        var delta = clock.getDelta();

        if ( mixer && play_center) mixer.update( delta );
        if ( mixer_left && play_left ) mixer_left.update( delta );
        if ( mixer_right && play_right ) mixer_right.update( delta );
        if ( mixer_back && play_back ) mixer_back.update( delta );

        renderer.render(scene, camera);

        update();
    }

    /* 初始加载 */
    (function () {
        console.log("three init start...");

        init();
        animate();

        console.log("three init send...");
    })();

</script>
</body>
</html>
